﻿using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using ABCat.Core;
using ABCat.Core.Plugins.Catalog.FilteringLogics;
using ABCat.Shared;
using ABCat.Shared.Properties;

namespace ABCat.Plugins.NormalizationSettingsEditor.Standard
{
	public class ReplacementTreeNode : INotifyPropertyChanged
	{
		private readonly Context _context;

		#region + Properties +

		public ObservableCollection<ReplacementTreeNode> Children		{get; set;}
		public string Value		{get; set;}
		public bool CanRemove { get; set; }
		public string RecordPropertyName { get; set; }
		public string ReplaceValue { get; set; }
		public string PossibleValue { get; set; }

		private readonly DelegateCommand _hideCommand;
		private readonly DelegateCommand _unHideCommand;

		public ICommand HideCommand
		{
			get
			{
				return _hideCommand;
			}
		}

		public ICommand UnHideCommand
		{
			get
			{
				return _unHideCommand;
			}
		}

		private bool _isHidden;

		public bool IsHidden
		{
			get
			{
				return _isHidden;
			}
			set
			{
				if (_isHidden == value) return;
				_isHidden = value;
				OnPropertyChanged();
			}
		}

		public bool CanHide { get; private set; }

		#endregion

		public ReplacementTreeNode(Context context, bool canHide)
		{
			CanHide = canHide;
			_context = context;
			_hideCommand = new DelegateCommand(parameter =>
			{
				using (var dbContainer = _context.CreateDbContainer(true))
				{
					var newHiddenValue = dbContainer.HiddenValueSet.CreateHiddenValue();
					newHiddenValue.WholeWord = true;
					newHiddenValue.IgnoreCase = true;
					newHiddenValue.PropertyName = RecordPropertyName;
					newHiddenValue.Value = ReplaceValue;
					dbContainer.HiddenValueSet.AddHiddenValue(newHiddenValue);
				}
				IsHidden = true;
				_context.PluginsFactory.GetPlugins<IFilteringLogicPlugin>().First().CreateInstance<IFilteringLogicPlugin>(_context).BeginUpdateCacheAsync(UpdateTypeEnum.Hidden, ex => { });
			}, parameter => !IsHidden);

			_unHideCommand = new DelegateCommand(parameter =>
			{
				using (var dbContainer = _context.CreateDbContainer(true))
				{
					dbContainer.HiddenValueSet.Delete(RecordPropertyName, Value);
				}
				IsHidden = false;
				_context.PluginsFactory.GetPlugins<IFilteringLogicPlugin>().First().CreateInstance<IFilteringLogicPlugin>(_context).BeginUpdateCacheAsync(UpdateTypeEnum.Hidden, ex => { });
			}, parameter => IsHidden);
		}

		#region + Logic +

		public override string ToString()
		{
			return Value;
		}

		#endregion

		public event PropertyChangedEventHandler PropertyChanged;

		[NotifyPropertyChangedInvocator]
		protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
		{
			PropertyChangedEventHandler handler = PropertyChanged;
			if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
		}
	}
}